package com.meta.platform.login.plus.vcode.service.impl;

import com.meta.act.app.service.*;
import com.meta.act.app.tenant.entity.TenantBase;
import com.meta.act.app.tenant.req.TenantDetailQry;
import com.meta.framework.act.entity.SysUser;
import com.meta.framework.act.model.LoginUser;
import com.meta.framework.common.constant.Constants;
import com.meta.framework.common.exception.BaseException;
import com.meta.framework.common.exception.CustomException;
import com.meta.framework.common.utils.MessageUtils;
import com.meta.framework.common.utils.SecurityUtils;
import com.meta.framework.manager.AsyncManager;
import com.meta.framework.manager.factory.AsyncFactory;
import com.meta.framework.service.TokenService;
import com.meta.platform.login.plus.common.vo.LoginSuccessVo;
import com.meta.platform.login.plus.security.LoginSimpleAuthenticationToken;
import com.meta.platform.login.plus.utils.VCodeUtils;
import com.meta.platform.login.plus.vcode.rest.req.FindPasswordCmd;
import com.meta.platform.login.plus.vcode.rest.req.RegisterCmd;
import com.meta.platform.login.plus.vcode.service.VCodeService;
import com.meta.platform.login.plus.vcode.service.VCodeUserService;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;

/**
 * 用户业务处理
 *
 * @author pengjianfeng
 * @version 1.0
 * @date 2021/1/12 3:48 下午
 */
@Service
public class VCodeUserServiceImpl implements VCodeUserService {
    
    @Resource
    private ISysUserService iSysUserService;
    
    @Resource
    private VCodeService vCodeService;
    
    @Resource
    private TenantQryService tenantQryService;
    
    @Resource
    private AuthenticationManager authenticationManager;
    
    @Resource
    private TokenService tokenService;
    
    /**
     * 账号注册
     * 
     * @param registerCmd 账号注册参数
     * @return
     */
    public LoginSuccessVo register(RegisterCmd registerCmd) {
        
        if (!VCodeUtils.isPhoneNumber(registerCmd.getPhoneNumber())) {
            throw new BaseException(MessageUtils.message("user.mobile.phone.number.not.valid"));
        }
        
        if (!VCodeUtils.checkPassword(registerCmd.getPassword())) {
            throw new BaseException(MessageUtils.message("user.password.not.valid"));
        }
        
        TenantDetailQry tenantDetailQry = new TenantDetailQry();
        tenantDetailQry.setTenantId(registerCmd.getTenantId());
        TenantBase detail = this.tenantQryService.queryTenantBase(tenantDetailQry);
        if (null == detail) {
            throw new BaseException(MessageUtils.message("tenant.no.exist"));
        }
        
//        // 验证验证码
        boolean verify = this.vCodeService.verifyVCode(registerCmd.getPhoneNumber(), registerCmd.getVCode());
        if (!verify) {
            return null;
        }
        // 获取域角色

        // 注册成功后，直接登录
        Authentication authentication;
        try {
            // 该方法会去调用VCodeUserDetailsService.loadUserByUsername
            authentication = authenticationManager.authenticate(new LoginSimpleAuthenticationToken(registerCmd.getPhoneNumber()));
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        catch (Exception e) {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(registerCmd.getPhoneNumber(), Constants.LOGIN_FAIL, e.getMessage()));
            throw new CustomException(e.getMessage());
        }
        
        AsyncManager.me()
            .execute(AsyncFactory
                .recordLogininfor(registerCmd.getPhoneNumber(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser)authentication.getPrincipal();
        
        return new LoginSuccessVo().setToken(tokenService.createToken(loginUser)).setUser(loginUser);
    }
    
    /**
     * 找回密码
     * 
     * @param findPasswordCmd 找回密码参数
     * @return
     */
    public int findPassword(FindPasswordCmd findPasswordCmd) {
        if (!VCodeUtils.isPhoneNumber(findPasswordCmd.getPhoneNumber())) {
            throw new BaseException(MessageUtils.message("user.mobile.phone.number.not.valid"));
        }
        
        if (!findPasswordCmd.getNewPassword().trim().equals(findPasswordCmd.getConfirmPassword())) {
            throw new BaseException(MessageUtils.message("user.password.no.eq.confirmPwd"));
        }
        
        if (!VCodeUtils.checkPassword(findPasswordCmd.getNewPassword())) {
            throw new BaseException(MessageUtils.message("user.password.not.valid"));
        }
        
        SysUser sysUser = this.iSysUserService.selectUserByUserName(findPasswordCmd.getPhoneNumber());
        if (null == sysUser) {
            throw new BaseException(MessageUtils.message("user.not.exists"));
        }
        
        sysUser.setPassword(SecurityUtils.encryptPassword(findPasswordCmd.getNewPassword()));
        sysUser.setUpdateBy(sysUser.getUserId());
        return this.iSysUserService.resetPwd(sysUser);
    }
}
